#include "stdafx.h"
#include "UIProperty.h"
#include "UIRuntimeObject.h"
#include "UICollections.h"
#include "UIAnimation.h"

namespace DirectUI
{
	bool CUIProperty::GetBOOLValue()
	{
		EnsureValueExist();
		return CUIObjectHelper(m_spValue).GetVal(false);
	}

	void CUIProperty::SetBOOLValue( bool val )
	{
		EnsureValueExist();
		bool OldVal = GetBOOLValue();
		CUIObjectHelper(m_spValue).SetVal(val);
		if ( OldVal != val )
			PropertyChanged();
	}

	int CUIProperty::GetIntValue()
	{
		EnsureValueExist();
		assert(m_ValObjectType==ot_int32);
		return CUIObjectHelper(m_spValue).GetVal(0);
	}

	void CUIProperty::SetIntValue( __int32 val )
	{
		EnsureValueExist();
		__int32 OldVal = GetIntValue();
		CUIObjectHelper(m_spValue).SetVal(val);
		if ( OldVal != val )
			PropertyChanged();
	}

	UIRect CUIProperty::GetRectValue()
	{
		EnsureValueExist();
		return CUIObjectHelper(m_spValue).GetVal(0, 0, 0, 0);
	}

	void CUIProperty::SetRectValue( UIRect val )
	{
		EnsureValueExist();
		UIRect OldVal = GetRectValue();
		CUIObjectHelper(m_spValue).SetVal(val);
		if ( memcmp(&OldVal, &val, sizeof(UIRect)) != 0 )
			PropertyChanged();
	}

	float CUIProperty::GetFloatValue()
	{
		EnsureValueExist();
		return CUIObjectHelper(m_spValue).GetVal((float)0);
	}

	void CUIProperty::SetFloatValue( float val )
	{
		EnsureValueExist();
		float OldVal = GetFloatValue();
		CUIObjectHelper(m_spValue).SetVal(val);
		if ( OldVal != val )
			PropertyChanged();
	}

	double CUIProperty::GetDoubleValue()
	{
		EnsureValueExist();
		return CUIObjectHelper(m_spValue).GetVal((double)0);
	}

	void CUIProperty::SetDoubleValue( double val )
	{
		EnsureValueExist();
		double OldVal = GetDoubleValue();
		CUIObjectHelper(m_spValue).SetVal(val);
		if ( OldVal != val )
			PropertyChanged();
	}

	DirectUI::UICOLOR CUIProperty::GetColorValue()
	{
		EnsureValueExist();
		return (UICOLOR)CUIObjectHelper(m_spValue).GetVal((__int32)0);
	}

	void CUIProperty::SetColorValue( UICOLOR val )
	{
		EnsureValueExist();
		__int32 OldVal = GetIntValue();
		CUIObjectHelper(m_spValue).SetVal((__int32)val);
		if ( OldVal != (__int32)val )
			PropertyChanged();
	}

	wchar_t* CUIProperty::GetStringValue()
	{
		EnsureValueExist();
		return CUIObjectHelper(m_spValue).GetVal((wchar_t*)NULL);
	}

	void CUIProperty::SetStringValue( wchar_t* val )
	{
		EnsureValueExist();
		wchar_t* OldVal = GetStringValue();
		CUIObjectHelper(m_spValue).SetVal(val);
		if ( wcscmp(OldVal, val) != 0 )
			PropertyChanged();
	}

	DirectUI::UIAlign CUIProperty::GetAlignValue()
	{
		EnsureValueExist();
		return (UIAlign)CUIObjectHelper(m_spValue).GetVal((__int32)0);
	}

	void CUIProperty::SetAlignValue( UIAlign val )
	{
		EnsureValueExist();
		__int32 OldVal = GetIntValue();
		CUIObjectHelper(m_spValue).SetVal((__int32)val);
		if ( OldVal != (__int32)val )
			PropertyChanged();
	}

	IUIPropertyEvent* CUIProperty::GetUIPropertyEvent()
	{
		IUIPropertyEvent* lpEvent = NULL;
		m_spTargetObj->QueryInterface(__uuidof(IUIPropertyEvent), (void**)&lpEvent);
		return lpEvent;
	}

	DirectUI::UITIMESPAN CUIProperty::GetTimeSpanValue()
	{
		EnsureValueExist();
		return (UITIMESPAN)CUIObjectHelper(m_spValue).GetVal((__int64)0);
	}

	void CUIProperty::SetTimeSpanValue( UITIMESPAN val )
	{
		EnsureValueExist();
		__int64 OldVal = GetTimeSpanValue();
		CUIObjectHelper(m_spValue).SetVal((__int64)val);
		if ( OldVal != (__int64)val )
			PropertyChanged();
	}

	void CUIProperty::ParseAttribute(xml_attribute& attr, IUIProperty* lpProperty)
	{
		if ( !lpProperty )
		{
			assert(false);
			return;
		}

		CUIObjectPtr<IUIProperty> spProperty = lpProperty;
		if ( !spProperty )
			return;

		switch ( spProperty->GetPropertyNameEnum() )
		{
		case Background:
			{
				spProperty->SetColorValue(CUIUtilityHelper::ParseColor(attr.value()));
				return;
			}
			break;

		case Stretch:
			{
				spProperty->SetIntValue(CUIUtilityHelper::ParseImageStretchMode(attr.value()));
				return;
			}
			break;

		case HorizontalAlignment:
		case VerticalAlignment:
		case AlignmentX:
		case AlignmentY:
			{
				spProperty->SetAlignValue(CUIUtilityHelper::ParseAlign(attr.value()));
				return;
			}
			break;

		default:
			break;
		}

		UIObjectType a = spProperty->GetValueType();
		switch ( spProperty->GetValueType() )
		{
		case ot_string:
			spProperty->SetStringValue((wchar_t*)attr.value());
			break;

		case ot_int32:
			spProperty->SetIntValue(CUIUtilityHelper::ParseInt(attr.value()));
			break;

		case ot_double:
			spProperty->SetDoubleValue(CUIUtilityHelper::ParseDouble(attr.value()));
			break;

		case ot_rect:
			{
				CRect rc(0, 0, 0, 0);
				rc = CUIObjectHelper::UIRectToRect(spProperty->GetRectValue());
				CUIUtilityHelper::ParseRect(attr.value(), rc);
				spProperty->SetRectValue(CUIObjectHelper::RectToUIRect(rc));
			}
			break;

		default:
			break;
		}
	}

	void CUIProperty::EnsureValueExist()
	{
		if ( !m_spValue )
			GetUICore()->GetUIObjectFactoryInstance()->CreateObject(NULL, m_ValObjectType, &m_spValue);
#ifdef DEBUG
		assert(m_spValue && m_spValue->GetObjType() == m_ValObjectType);
#endif
	}

	void CUIProperty::TimelineParseAttribute( xml_attribute& attr, IUIProperty* lpProperty )
	{
		if ( !lpProperty )
		{
			assert(false);
			return;
		}

		CUIObjectPtr<IUIProperty> spProperty = lpProperty;
		if ( !spProperty )
			return;

		switch ( spProperty->GetPropertyNameEnum() )
		{
		case DirectUI::UIAnimation::From_Color:
		case DirectUI::UIAnimation::To_Color:
		case DirectUI::UIAnimation::By_Color:
			{
				spProperty->SetColorValue(CUIUtilityHelper::ParseColor(attr.value()));
				return;
			}
			break;

		case DirectUI::UIAnimation::BeginTime:
		case DirectUI::UIAnimation::Duration:
			{
				spProperty->SetTimeSpanValue(CUIUtilityHelper::ParseTimeSpan(attr.value()));
				return;
			}
			break;

		default:
			break;
		}

		UIObjectType a = spProperty->GetValueType();
		switch ( spProperty->GetValueType() )
		{
		case ot_string:
			spProperty->SetStringValue((wchar_t*)attr.value());
			break;

		case ot_int32:
			spProperty->SetIntValue(CUIUtilityHelper::ParseInt(attr.value()));
			break;

		case ot_double:
			spProperty->SetDoubleValue(CUIUtilityHelper::ParseDouble(attr.value()));
			break;

		case ot_rect:
			{
				CRect rc(0, 0, 0, 0);
				rc = CUIObjectHelper::UIRectToRect(spProperty->GetRectValue());
				CUIUtilityHelper::ParseRect(attr.value(), rc);
				spProperty->SetRectValue(CUIObjectHelper::RectToUIRect(rc));
			}
			break;

		default:
			assert(false);
			break;
		}
	}

	void CUIProperty::PropertyChanged()
	{
		IUIPropertyEvent* p = GetUIPropertyEvent();
		if ( p )
			p->PropertyChanged(m_NameEnum);

	}

}